#include "dre_bus_safe.h"
#include "main.h"

static volatile uint8_t  g_u8a_exch_tx_buf[EXCH_SIZE_MAX] = {0u};
static volatile uint8_t  g_u8a_exch_rx_buf[EXCH_SIZE_MAX] = {0u};
//dre_safe_info_t	st_dre_sf;
static  dre_safe_info_t	st_dre_sf;

void dre_init(bool_t b8_is_master)/*主从SPI初始化*/
{

	if(EXCH_SIZE_MAX < sizeof(exch_com_run_dat_t))
	{
		while(1)
		{
			;
		}
	}
	else
	{
		;
	}
	
	exch_spi_init(b8_is_master);//SPI硬件初始化
	exch_init_val();//SPI-DMA缓冲区数据清0
	dre_init_val(); //SPI通讯数据初始化
	exch_spi_disable();//SPI-DMA关闭
	if(b8_is_master == BFALSE) //若为从SPI
	{
		exch_set_slave_trigger(BFALSE); //置从SPI未准备好
	}
	else
	{
		;
	}
}

 void dre_init_val(void)
{
	uint16_t	u16_idx	= 0u;
	
	//g_u16_safe_sn	= 0u;
	
	for(u16_idx = 0u; u16_idx < EXCH_SIZE_MAX; u16_idx ++)
	{
		g_u8a_exch_tx_buf[u16_idx] = 0u;          //DMA_TX buf 初始化
		g_u8a_exch_rx_buf[u16_idx] = 0u;          //DMA_RX buf 初始化
	}
	st_dre_sf.em_sf_sta					= DRE_IDLE;      //SPI发送状态机 空闲状态
	st_dre_sf.st_sf_err.u32_timeout_cnt	= 0u;
	st_dre_sf.st_sf_err.u16_tim_old		= comm_tim_get_currt_cnt();//获得当前计数值
  st_dre_sf.st_sf_err.u16_err_cnt		= 0u;
	st_dre_sf.st_sf_err.b8_err			= BFALSE;
}

 void dre_syn_handle(uint8_t u8_mcu_addr)
{
	uint32_t	u32_tmp_dat		= 0u;
	
	if(u8_mcu_addr == ADDR_MCU_B)
	{
		u32_tmp_dat = comm_tim_calc_diff(&st_dre_sf.st_syn_tim.u16_tim_old);//得到当前的时间
		if(st_dre_sf.st_syn_tim.u16_cnt < DRE_SYN_TIME)
		{
			st_dre_sf.st_syn_tim.u16_cnt += (uint16_t)u32_tmp_dat;//累加当前差值
		}
		else
		{
			st_dre_sf.st_syn_tim.u16_cnt = 0u;
			st_dre_sf.st_syn_tim.u16_tim_old = comm_tim_get_currt_cnt();//把当前值给老值
			
			if(st_dre_sf.u16_step_tx < DRE_SYN_STEP_MAX)  //800
			{
				st_dre_sf.u16_step_tx ++; 
				// step_tx 的作用主要用于DI /DO的诊断，DI部分产生脉冲信号：
				// STEP-TX为偶数时MCUA产生脉冲，为奇数时MCUB产生脉冲；
				//STEP-TX为64的倍数做DO诊断，但不同的倍数，做不同的pattern(规则)
			}
			else
			{
				st_dre_sf.u16_step_tx = 0u;
			}
		}
	}
	else if(u8_mcu_addr == ADDR_MCU_A)
	{

	}
	else
	{
		st_dre_sf.u16_step_tx = 0u;
	}
	
}
          //dre_fill_tx_dat((exch_com_run_dat_t*)g_u8a_exch_tx_buf, 1u);//把代发送数据写到g_u8a_exch_tx_buf
static void dre_fill_tx_dat(exch_com_run_dat_t	*stp_spi_dat, uint8_t u8_fc )
{
	uint16_t	u16_idx		= 0u;
	uint8_t u8_temp;
	uint16_t  u16_crc_config_temp=0u;
	u16_crc_config_temp = CodeCRCCal((uint8_t*)&g_st_ram1, (NUM_LOGIC*12u)+88u);  // 组态数据校验
	g_st_ram1.run_display_data.u16_config_crc=u16_crc_config_temp; //每个周期计算一次CRC,并存入RAM中
	g_st_ram2.run_display_data.u16_config_crc=u16_crc_config_temp; //每个周期计算一次CRC,并存入RAM中
	switch (u8_fc)
	{
		case 1u:
		{
			
      stp_spi_dat->u8_sd	= DRE_SD;   //SPI数据帧开始
	    stp_spi_dat->u8_fc	= 0x01u;    //功能码
			stp_spi_dat->u8_le	= 76u;       //长度	 
			stp_spi_dat->com_run_display_data.u8_mcu_addr		   = g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr;
			stp_spi_dat->com_run_display_data.u8_dev_fault		 = g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault;
      stp_spi_dat->com_run_display_data.u16_di           = g_st_ram1.run_display_data.instrument_hmi.u16_di;
			stp_spi_dat->com_run_display_data.u16_do           = g_st_ram1.run_display_data.instrument_hmi.u16_do;
			stp_spi_dat->com_run_display_data.u8_led_sta[0]    = g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[0];
			stp_spi_dat->com_run_display_data.u8_led_sta[1]    = g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[1];
			stp_spi_dat->com_run_display_data.u8_led_sta[2]    = g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[2];
			stp_spi_dat->com_run_display_data.u8_led_sta[3]    = g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[3];
			stp_spi_dat->com_run_display_data.u8_led_sta[4]    = g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[4];
			stp_spi_dat->com_run_display_data.u8_led_sta[5]    = g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[5];
			stp_spi_dat->com_run_display_data.u16_run_temper   = g_st_ram1.run_display_data.instrument_hmi.u16_run_temper; 
			stp_spi_dat->com_run_display_data.u16_pwr_in       = g_st_ram1.run_display_data.instrument_hmi.u16_pwr_in; 
			stp_spi_dat->com_run_display_data.u16_pwr_coil     = g_st_ram1.run_display_data.instrument_hmi.u16_pwr_coil; 
			stp_spi_dat->com_run_display_data.u16_adc_vref     = g_st_ram1.run_display_data.instrument_hmi.u16_adc_vref; 
			stp_spi_dat->com_run_display_data.u32_st_dev_sta   = g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta;
			stp_spi_dat->com_run_display_data.u16_vrefint_cal  = g_st_ram1.run_display_data.u16_vrefint_cal;
			stp_spi_dat->com_run_display_data.u16_ts_cal1      = g_st_ram1.run_display_data.u16_ts_cal1;
			
      stp_spi_dat->com_run_display_data_rev.u8_mcu_addr     = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr;
			stp_spi_dat->com_run_display_data_rev.u8_dev_fault    = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault;
			stp_spi_dat->com_run_display_data_rev.u16_di          = (uint16_t)~g_st_ram1.run_display_data.instrument_hmi.u16_di;
			stp_spi_dat->com_run_display_data_rev.u16_do          = (uint16_t)~g_st_ram1.run_display_data.instrument_hmi.u16_do;
			stp_spi_dat->com_run_display_data_rev.u8_led_sta[0]   = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[0];
			stp_spi_dat->com_run_display_data_rev.u8_led_sta[1]   = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[1];
			stp_spi_dat->com_run_display_data_rev.u8_led_sta[2]   = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[2];
			stp_spi_dat->com_run_display_data_rev.u8_led_sta[3]   = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[3];
			stp_spi_dat->com_run_display_data_rev.u8_led_sta[4]   = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[4];
			stp_spi_dat->com_run_display_data_rev.u8_led_sta[5]   = (uint8_t)~g_st_ram1.run_display_data.instrument_hmi.u8_led_sta[5];			
			stp_spi_dat->com_run_display_data_rev.u16_run_temper  = (uint16_t)~g_st_ram1.run_display_data.instrument_hmi.u16_run_temper; 
			stp_spi_dat->com_run_display_data_rev.u16_pwr_in      = (uint16_t)~g_st_ram1.run_display_data.instrument_hmi.u16_pwr_in; 
			stp_spi_dat->com_run_display_data_rev.u16_pwr_coil    = (uint16_t)~g_st_ram1.run_display_data.instrument_hmi.u16_pwr_coil; 
			stp_spi_dat->com_run_display_data_rev.u16_adc_vref    = (uint16_t)~g_st_ram1.run_display_data.instrument_hmi.u16_adc_vref; 
			stp_spi_dat->com_run_display_data_rev.u32_st_dev_sta  = (uint32_t)~g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta;
			stp_spi_dat->com_run_display_data_rev.u16_vrefint_cal = (uint16_t)~g_st_ram1.run_display_data.u16_vrefint_cal; 
			stp_spi_dat->com_run_display_data_rev.u16_ts_cal1     = (uint16_t)~g_st_ram1.run_display_data.u16_ts_cal1;

		}break;
		default: break;
	}
	//stp_spi_dat->u16_replay_pc = 0u;
	stp_spi_dat->u16_diag_step   =  st_dre_sf.u16_step_tx ;  //诊断计数
	if(g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr  == ADDR_MCU_B )
	{
//		if( (stp_spi_dat->u16_OutputCheckSM) != g_st_ram1.run_auxiliary_data.TimeStepNum)  //判读收到的值与本地比较是否一致
//		{
//		  g_st_ram1.run_auxiliary_data.TimeStepNum = (stp_spi_dat->u16_OutputCheckSM);   //不一致将SPI的值更新至本地ram里
//		}
   if( g_st_ram1.run_auxiliary_data.TimeStepNum > (stp_spi_dat->u16_OutputCheckSM))	          
		{
      (stp_spi_dat->u16_OutputCheckSM) =  g_st_ram1.run_auxiliary_data.TimeStepNum;    //安全输出交叉诊断	
		}
		else 
		{
			;
		}
	//	g_st_ram1.run_auxiliary_data.TimeStepNum = (stp_spi_dat->u16_OutputCheckSM);   //不一致将SPI的值更新至本地ram里
	}
	else 
	{
		if( g_st_ram1.run_auxiliary_data.TimeStepNum > (stp_spi_dat->u16_OutputCheckSM))
		{
	    stp_spi_dat->u16_OutputCheckSM =  g_st_ram1.run_auxiliary_data.TimeStepNum;    //安全输出交叉诊断
		}
		else 
		{ 
         ;			
		 }
	}

	
  if	(g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr == ADDR_MCU_A) 
	  {
			stp_spi_dat->u16_mcua_di    =  g_st_ram1.run_auxiliary_data.u16_mcua_di ; 
			stp_spi_dat->u16_mcua_do    =  g_st_ram1.run_auxiliary_data.u16_mcua_do ; 
			stp_spi_dat->u16_mcub_di  =0u;
			stp_spi_dat->u16_mcub_do  =0u;
		}
	else
		{
			stp_spi_dat->u16_mcua_di  =0u;
			stp_spi_dat->u16_mcua_do  =0u;
			stp_spi_dat->u16_mcub_di   =  g_st_ram1.run_auxiliary_data.u16_mcub_di ;   
			stp_spi_dat->u16_mcub_do   =  g_st_ram1.run_auxiliary_data.u16_mcub_do ;   
		}
	stp_spi_dat->u16_crc_config = u16_crc_config_temp;            //传输CRC   用户组态数据的校验
	stp_spi_dat->u16_crc_frame =  CodeCRCCal((uint8_t*)stp_spi_dat, 72u) ;     // 直接给出数据长度 
	stp_spi_dat->u8_ed  = DRE_ED;
}

 bool_t dre_compare_safe_dat(uint8_t u8a_dat[], uint8_t u8a_rev[], uint16_t u16_len) //比较数据安全
{
	uint16_t	u16_idx		= 0u;
	uint8_t		u8_dat		= 0u;
	bool_t		b8_rtn_err	= BFALSE;
	for(u16_idx = 0u; u16_idx < u16_len; u16_idx ++){
		u8_dat	= (uint8_t)~u8a_rev[u16_idx];
		if(u8a_dat[u16_idx] != u8_dat){
			b8_rtn_err	= BTRUE;
		}
		else{
			;
		}
	}
	return b8_rtn_err;
}

//处理数据帧
static void dre_get_rx_dat(exch_com_run_dat_t	*stp_spi_dat)
{
	bool_t		b8_dat_err	= BFALSE;
	uint16_t	u16_crc16	= 0u;
	
  	if((stp_spi_dat->u8_sd == DRE_SD) && (stp_spi_dat->u8_ed == DRE_ED))
		  {
			 b8_dat_err = dre_compare_safe_dat((uint8_t*)(&stp_spi_dat->com_run_display_data),(uint8_t*)(&stp_spi_dat->com_run_display_data_rev),28u);  //zhou 正确 24
			if(b8_dat_err == BFALSE)
				{
				     u16_crc16 = CodeCRCCal((uint8_t*)stp_spi_dat, 72u);  //SPI数据帧的校验
				         if(u16_crc16 == (stp_spi_dat->u16_crc_frame))
			            	{
					            /* data correct */
											dre_safe_reco();//通讯数据正常后，进行正确计数，发生错误的故障次数和恢复故障的次数比例为1：4
											st_dre_sf.u16_step_rx		= stp_spi_dat->u16_diag_step;
											if (g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr == ADDR_MCU_A)
											{
												g_st_ram1.run_auxiliary_data.u16_mcub_di = stp_spi_dat-> u16_mcub_di;
												g_st_ram1.run_auxiliary_data.u16_mcub_do = stp_spi_dat-> u16_mcub_do;
												g_st_ram2.run_auxiliary_data.u16_mcub_di = stp_spi_dat-> u16_mcub_di;
												g_st_ram2.run_auxiliary_data.u16_mcub_do = stp_spi_dat-> u16_mcub_do;
//												u16_sm_step =  stp_spi_dat->u16_OutputCheckSM;
													if(g_st_ram1.run_auxiliary_data.TimeStepNum < stp_spi_dat->u16_OutputCheckSM)
													{
														g_st_ram1.run_auxiliary_data.TimeStepNum = stp_spi_dat->u16_OutputCheckSM;
														g_st_ram2.run_auxiliary_data.TimeStepNum = stp_spi_dat->u16_OutputCheckSM;	
													}
													else 
													{
													 ;
													}
											}
											else
											{
												g_st_ram1.run_auxiliary_data.u16_mcua_di = stp_spi_dat-> u16_mcua_di;
												g_st_ram1.run_auxiliary_data.u16_mcua_do = stp_spi_dat-> u16_mcua_do;
												g_st_ram2.run_auxiliary_data.u16_mcua_di = stp_spi_dat-> u16_mcua_di;
												g_st_ram2.run_auxiliary_data.u16_mcua_do = stp_spi_dat-> u16_mcua_do;
												
												 if(g_st_ram1.run_auxiliary_data.TimeStepNum < stp_spi_dat->u16_OutputCheckSM)
													{
													g_st_ram1.run_auxiliary_data.TimeStepNum = stp_spi_dat->u16_OutputCheckSM;
													g_st_ram2.run_auxiliary_data.TimeStepNum = stp_spi_dat->u16_OutputCheckSM;
													}
													else 
													{ 
														;
													}
											}
											g_st_ram1.run_auxiliary_data.u32_st_dev_sta = stp_spi_dat-> com_run_display_data.u32_st_dev_sta;
											g_st_ram2.run_auxiliary_data.u32_st_dev_sta = stp_spi_dat-> com_run_display_data.u32_st_dev_sta;
//											g_st_ram1.run_auxiliary_data.u16_dev_di = stp_spi_dat->;
				            }
				         else
				         {
				        	 ;
				         }
			 }
		 else
		 {
			 ;
		 }
	   }
    else
    {
    	;
    }
}

void dre_safe_poll(const uint8_t u8lc_init_val, const uint8_t u8lc_incr_val)
{
	uint32_t	u32_tmp_dat		= 0u;
	
	diag_rcd_run_logic(u8lc_init_val, u8lc_incr_val); //程序序列监控诊断
	
	u32_tmp_dat = comm_tim_calc_diff(&st_dre_sf.st_sf_err.u16_tim_old);
	//读取当前时间和上一次时间的差值，并覆盖上一次时间
	if(st_dre_sf.st_sf_err.u32_timeout_cnt < DRE_SAFE_TIMEOUT)//DRE_SAFE_TIMEOUT 1000ms 超时监控
	{
		st_dre_sf.st_sf_err.u32_timeout_cnt += u32_tmp_dat;   //≤1000ms,继续增加
	}
	else
	{
		if(st_dre_sf.st_sf_err.u16_err_cnt < DRE_SAFE_MAX_ERR)   //16u
		{
			st_dre_sf.st_sf_err.u16_err_cnt += 1u;  //≤4s,没通讯上，不导向安全 4
		}
		else
		{
			st_dre_sf.st_sf_err.b8_err = BTRUE; //若＞4s,没通讯成功，则导向安全，只有断电重启才能消除
			g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault |= BF_DIAG1_COMM;  
			g_st_ram2.run_display_data.instrument_hmi.u8_dev_fault |= BF_DIAG1_COMM; 	
			if (g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr == ADDR_MCU_A)
						{
							g_st_ram1.run_auxiliary_data.u16_mcub_di = 0u;
							g_st_ram2.run_auxiliary_data.u16_mcub_di = 0u;
						}
			else
						{
							g_st_ram1.run_auxiliary_data.u16_mcua_di = 0u;
							g_st_ram2.run_auxiliary_data.u16_mcua_di = 0u;
						}
		}
		st_dre_sf.st_sf_err.u32_timeout_cnt	= 0u; //清0处理
	}
	
	/* MCU A & B synchronization */
	dre_syn_handle(g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr); //两个MCU同步用于DI脉冲的同步,MCUB产生同步步数
	/* DRE-BUS data layer */
	dre_protocol_poll(); //用于数据的交换
}

 void dre_safe_reco(void)
{
	st_dre_sf.st_sf_err.u32_timeout_cnt	= 0u;
	st_dre_sf.st_sf_err.u16_tim_old		= comm_tim_get_currt_cnt();
	
	if(0u < st_dre_sf.st_sf_err.u16_err_cnt)
	{
		st_dre_sf.st_sf_err.u16_err_cnt -= 1u;
	}
	else
	{
		st_dre_sf.st_sf_err.b8_err = BFALSE; //置通讯故障为0，为0代表无故障
	}
}


uint16_t dre_get_diag_tx_step(void)  //MCUB是对外发送步数
{
	return st_dre_sf.u16_step_tx;
}

void dre_set_diag_tx_step(uint16_t u16_step)
{
	st_dre_sf.u16_step_tx	= u16_step;
}

uint16_t dre_get_diag_rx_step(void)  //MCUA是接收到同步步数
{
	return st_dre_sf.u16_step_rx;
}

void dre_set_diag_ack_step(uint16_t u16_step)
{
	st_dre_sf.u16_step_ack	= u16_step;
}

void dre_protocol_poll(void)
{
	bool_t	b8_spi_busy		= BTRUE;
	bool_t	b8_slave_trigger	= BFALSE;
	bool_t	b8_master_ready		= BFALSE;
	static bool_t	s_b8_slave_trigger_tx	= BFALSE;
	static bool_t	s_b8_slave_trigger_rx	= BFALSE;
	uint8_t	u8_err			= EXCH_RTN_OK;
	
	bool_t	b8_is_master	= BFALSE;
	
	uint32_t		u32_tmp_dat			= 0u;
	static uint32_t	s_u32_timeout_cnt	= 0u;//SPI过程中
	static uint16_t	s_u16_phys_tim_old	= 0u;
	
	/* DRE-BUS Safe layer Error check */
	/* dre_safe_poll(); */
	/* MCU A & B synchronization */
	/* dre_syn_handle(g_st_ram1.u8_mcu_addr); */
	/* DRE-BUS Physics layer manage */
	if(g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr == ADDR_MCU_B)
	{
		/* MCU B */
		b8_is_master = BTRUE;  //MCUb 为SPI主机
	}
	else
	{
		/* MCU A */
		b8_is_master = BFALSE; //MCUa 为SPI从机，但和uart进行通讯
	}
	
	switch(st_dre_sf.em_sf_sta)
	{
	case DRE_IDLE :// 空闲状态
	{
		/* Fill send data */
		dre_fill_tx_dat((exch_com_run_dat_t*)g_u8a_exch_tx_buf,1u);//把代发送数据写到g_u8a_exch_tx_buf
	
		u8_err = exch_set_dat(g_u8a_exch_tx_buf, EXCH_SIZE_MAX);//把g_u8a_exch_tx_buf传到DMA发送部分
		if(u8_err == EXCH_RTN_OK)
		{
			/* Send data */
			st_dre_sf.em_sf_sta = DRE_START; //设置状态机为启动状态
			s_u32_timeout_cnt = 0u;
			s_u16_phys_tim_old = comm_tim_get_currt_cnt();//得到当前时间
			 
			if(BTRUE == b8_is_master)
			{
				exch_set_master_ready(BTRUE);//置状态线为1，主机告知从机数据已准备好
			}
			else
			{
				;
			}
		}
		else
		{
			; /* Fill data fail */
		}
		if(((g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault & BF_DIAG1_COMM) != 0u) || \
		((g_st_ram2.run_display_data.instrument_hmi.u8_dev_fault & BF_DIAG1_COMM) != 0u))
		{
			exch_spi_init(b8_is_master); //若通讯出错，则从新初始化SPI接口
		}
		else
		{
			;
		}
		break;
	}
	case DRE_START ://启动发送装态
	{
		/* Check Ready signal */
		b8_slave_trigger	= exch_get_slave_trigger();
		b8_master_ready		= exch_get_master_ready();
		if(BFALSE == b8_is_master)  //若为从机
		{
			if(b8_master_ready == BTRUE)//先读master Ready线是否为高，为高代表准备好
			{
				exch_spi_enable(b8_is_master);//根据输入参数使能SPI,1的时候主机使能，0的时候从机使能
				st_dre_sf.em_sf_sta = DRE_XFER;//置状态位为数据传输
				if(s_b8_slave_trigger_tx == BFALSE)
				{
					s_b8_slave_trigger_tx = BTRUE;//从机产生跳变沿
				}
				else
				{
					s_b8_slave_trigger_tx	= BFALSE;//从机产生跳变沿
				}
				exch_set_slave_trigger(s_b8_slave_trigger_tx);//控制I/O-直接输出到端口上
			}
			else
			{
				exch_set_slave_trigger(s_b8_slave_trigger_tx);//控制I/O-直接输出到端口上
			}
		}
		else if(s_b8_slave_trigger_rx != b8_slave_trigger)//读取从机Trigger线是否发生跳变，若跳变则启动发送
		{	/* Trigger */
			exch_spi_enable(b8_is_master); //根据输入参数使能SPI,1的时候主机使能，0的时候从机使能，数据传输开始
			st_dre_sf.em_sf_sta = DRE_XFER;//置状态位为数据传输
			s_b8_slave_trigger_rx	= b8_slave_trigger;//更新主机读到的从机Triger线状态
			
			exch_set_master_ready(BFALSE); //置主机ready线为0,告知从机现在忙碌
		}
		else
		{
			;	/* Wait */
		}
		s_u32_timeout_cnt = 0u;//置定时器时间为0
		s_u16_phys_tim_old = comm_tim_get_currt_cnt();//读取当前时间
		
		break;
	}
	case DRE_XFER : //数据处理
	{
		
		b8_spi_busy = exch_spi_is_busy();//读取SPI寄存器状态位-busy状态状态
		/* u16_curt_tx_cnt = DMA_GetCurrDataCounter(DMA1_Channel3); */
		u32_tmp_dat = comm_tim_calc_diff(&s_u16_phys_tim_old);//计算定时器差值，时间间隔
		s_u32_timeout_cnt += u32_tmp_dat;//加上时间间隔
		if(BFALSE == b8_spi_busy)//SPI空闲状态
		{
			exch_spi_disable();//关闭SPI
			/* Handle data */
			u8_err = exch_get_dat(g_u8a_exch_rx_buf, EXCH_SIZE_MAX);//获取SPI接收到的数据，数据长度位116字节
			
			if(u8_err == EXCH_RTN_OK)
			{
				/* Handle receive data */
				dre_get_rx_dat((exch_com_run_dat_t*)g_u8a_exch_rx_buf);//对接收到的SPI数据进行处理，判断数据帧正确与否等
				u8_err = EXCH_RTN_OK;
			}
			else
			{
				; /* Receive data incorrectness */
			}
			st_dre_sf.em_sf_sta = DRE_IDLE;//置状态位为空闲
			s_u32_timeout_cnt = 0u;
			s_u16_phys_tim_old = comm_tim_get_currt_cnt();
		}
		else if(DRE_PHYS_TIMEOUT < s_u32_timeout_cnt)
		{	/* Timeout */
			exch_spi_disable();//先disable
			exch_spi_init(b8_is_master);//再初始化下
			st_dre_sf.em_sf_sta = DRE_IDLE;//置状态位为空闲
			s_u32_timeout_cnt = 0u;
			s_u16_phys_tim_old = comm_tim_get_currt_cnt();
		}
		else
		{
			;	/* Wait */
		}
		break;
	}
	default : break;
	}
}



